/*
 * Description: 开机自启动项管理
 */
#include "autorun_manager.h"
#include "Windows.h"
#include "performance/utils/registry_utils.h"
#include "performance/utils/registry_utils_ex.h"
#include "common/guest_utils.h"
#include "log.h"

namespace PERF {

constexpr const DWORD SERVICE_START_OFF = 4;

bool AutorunManager::RemoveAutorun(const Autorun &autorun)
{
    if (!autorun.shouldRemove) {
        return true;
    }
    bool ret = true;
    ret &= RemoveAutorunFromRegistry(autorun);
    ret &= RemoveAutorunFromPath(autorun);
    ret &= RemoveAutorunFromService(autorun);
    ret &= RemoveAutorunFromScheduledTask(autorun);
    return ret;
}

bool AutorunManager::RemoveAutorunFromRegistry(const Autorun &autorun)
{
    HKEY hkcu = nullptr;
    REGISTRY_UTILS.GetHKCU(hkcu);
    if (hkcu == nullptr) {
        LOG_ERR("[PERF - RemoveAutorunFromRegistry] - hkcu is null");
        return false;
    }
    for (auto entry : autorun.registry) {
        HKEY hRoot = nullptr;
        if (entry.first == "HKCU_KEYS") {
            hRoot = hkcu;
        } else {
            hRoot = HKEY_LOCAL_MACHINE;
        }
        for (Registry registry : entry.second) {
            LOG_INFO("[PERF - RemoveAutorunFromRegistry] - key: {}, item: {}", registry.key, registry.item);
            HKEY subKey = nullptr;
            if (!REGISTRY_UTILS.GetRegKey(hRoot, registry.key.c_str(), subKey)) {
                LOG_ERR("[PERF - RemoveAutorunFromRegistry] - GetRegKey failed.");
                REGISTRY_UTILS.SafeCloseHKey(hkcu);
                return false;
            }
            RegDeleteValue(subKey, registry.item.c_str());
            REGISTRY_UTILS.SafeCloseHKey(subKey);
        }
    }
    REGISTRY_UTILS.SafeCloseHKey(hkcu);
    return true;
}

bool AutorunManager::RemoveAutorunFromPath(const Autorun &autorun)
{
    bool ret = true;
    for (std::string path : autorun.paths) {
        ret &= DeleteFile(path.c_str());
    }
    return ret;
}

bool AutorunManager::RemoveAutorunFromService(const Autorun &autorun)
{
    bool ret = true;
    for (auto service : autorun.services) {
        ret &= REGISTRY_UTILS.SetRegDWORD(HKEY_LOCAL_MACHINE, service.key.c_str(), service.item.c_str(),
                                          SERVICE_START_OFF);
    }
    return ret;
}

bool AutorunManager::RemoveAutorunFromScheduledTask(const Autorun &autorun)
{
    for (std::string scheduledTask : autorun.scheduledTasks) {
        std::string cmd = "schtasks.exe /change /DISABLE /tn " + scheduledTask;
        COMMON::GuestUtils::ExecCmd(cmd, false);
    }
    return true;
}

}
